package abacab.router;

import java.util.Arrays;

import abacab.actor.Actor;
import abacab.actor.ActorDef;
import abacab.exec.MessageExecutor;
import abacab.message.Envelope;
import abacab.ref.AbstractActorRef;

/**
 * A router that notifies all actors for each message
 * 
 * @param <M>
 *          the type of handled messages
 */
public class MulticastRouter<M> extends AbstractRouter<M> {
	/** The actors */
	private final Actor<? super M>[]	actors;

	/**
	 * Create the router
	 * 
	 * @param nbActors
	 *          the number of actors
	 */
	@SuppressWarnings("unchecked")
	public MulticastRouter(int nbActors) {
		this.actors = new Actor[nbActors];
	}

	@Override
	public void init(AbstractActorRef<M> actorRefP, ActorDef<M> definitionP) {
		super.init(actorRefP, definitionP);
		for (int i = 0; i < this.actors.length; i++) {
			this.actors[i] = buildActor(Integer.toString(i));
			this.actors[i].init();
		}
	}

	@Override
	public Actor<? super M>[] getActors() {
		return Arrays.copyOf(this.actors, this.actors.length);
	}

	@Override
	public void send(MessageExecutor executor, Envelope<M> message) {
		for (Actor<? super M> actor : this.actors) {
			actor.getActorContext().getQueue().offer(message);
			executor.queueForExecution(actor);
		}
	}
}